ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                   *** Join levels ***
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; An utility to join Bolder Dash levels, into one multi
; level file. NOT user friendly :)
; Protected mode, DOS32, messy code.
;
;  (C) Copyright 1997  Suicide Software  All Rights Reserved.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


        IDEAL
        P386N


ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; *** Equates and Numbers ***
CR              EQU     13
LF              EQU     10
EOS             EQU     '$'
Debugging       =       1


; *** Setup segment order ***
SEGMENT         BigSeg          DWORD           Public          USE32
EndS            BigSeg
SEGMENT         U_DATA          DWORD           Public          USE32
EndS            U_DATA


; *** Files to include ***
INCLUDE         "STUFF.INC"
INCLUDE         "STR.INC"
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


EXTRN   Debug:Proc

ASSUME  CS:BigSeg

SEGMENT         BigSeg
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                           *** CODE ***
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Start:  call    Init

        call    Get_Param               ; Get command line string
        cmp     bl,2
        mov     esi,Offset Str_Err1     ; Exit if no file name is given...
        jl      Exit_Write

        Say "Loading index file..."


; Load index file...
        mov     cx,1
        call    One_Param
        mov     edi,Offset Buffer
        call    Load_File               ; ESI = File name
        jc      Disk_Error

; Convert CR to 0
        mov     esi,Offset Buffer
@@00:   lodsb
        cmp     al,'*'
        je      @@01
        cmp     al,CR
        jne     @@00
        mov     [Byte ds:esi-1],0
        jmp     @@00


@@01:   Say "Try to allocate 1 MB of memory..."

; Allocate memory...
        mov     ax,0EE42h
        mov     edx,1024*1024           ; 1MB
        int     31h
        mov     esi,Offset Str_GenError
        or      eax,eax
        jz      Exit_Write
        mov     [Dword ds:Mem_Offset],edx       ; Save offset to memmory

; Write intro message...
        mov     esi,Offset Str_Intro
        call    Str_Write

; Ok, start to join file names
        mov     edi,[Dword ds:Mem_Offset]       ; Build header...
        mov     esi,Offset Buffer
        xor     eax,eax
        mov     ax,[Word ds:esi]                ; Header size
        cmp     ah,'!'                          ; File ID ok?
        jne     Exit
        sub     al,'0'                          ; Convert to binary
        xor     ah,ah
        mov     ebx,32
        mul     ebx                             ; EAX = Size * 32
        mov     [Dword ds:edi],'1-DB'           ; File ID
        mov     ebx,edi
        add     ebx,4                           ; EBX = Offset to index table
        add     edi,eax
        mov     ebp,eax                         ; EBP = New file size
        xor     edx,edx                         ; EDX = Level number

        add     esi,4                           ; First file name


; *****************
; *** Main loop ***
; *****************
@@10:   cmp     [Byte ds:esi],'*'               ; Done?
        je      @@90

        push    ebx edx esi
        mov     esi,Offset Str_Join             ; Write status string
        call    Str_Write
        mov     esi,[Dword ss:esp]              ; Get esi from stack
        call    Str_Write

        call    Load_File                       ; Load first level.
        jnc     @@20
        mov     esi,Offset Str_Err2             ; Disk error
        jmp     Exit_Write


; Update new index table (EAX = Bytes loaded / added)
@@20:   pop     esi edx ebx

        mov     ecx,edi
        sub     ecx,[Dword ds:Mem_Offset]       ; Relativ offset to level
        shr     ecx,4                           ; Convert to SEG
        mov     [Dword ds:ebx],ecx              ; Uppdate index table
        add     ebx,2                           ; Next entry in index table

        mov     ecx,eax                         ; Para align
        and     ecx,0Fh                         ; Only want 4 lower bits
        or      cl,cl                           ; Allready aligned
        jz      @@25
        neg     ecx                             ; Allign...
        add     eax,ecx

@@25:   add     ebp,eax                         ; New size
        add     edi,eax                         ; EDI = New position

        push    ebx edx esi                     ; Write rest of status string
        mov     esi,Offset Str_Join2
        call    Str_Write
        pop     esi edx ebx

        inc     edx                             ; Level count
@@30:   lodsb                                   ; Next line in index list
        cmp     al,LF
        jne     @@30

        jmp     @@10                            ; This should work...


; *** Finaly, we are done ***
@@90:   mov     [Word ds:ebx],-1                ; End of new index list

        call    New_Line

        Say "Creating and write to new file..."

        mov     cx,2                    ; Get param number 2
        call    One_Param

        mov     ah,03Ch                 ; Create new file
        xor     cx,cx
        mov     edx,esi
        int     21h
        jc      Disk_Error
        mov     bx,ax                   ; Handle

        mov     ah,040h                 ; Write to file
        mov     ecx,ebp                 ; File size (from previos routine)
        mov     edx,[Dword ds:Mem_Offset]
        int     21h
        jc      Disk_Error

        mov     ah,03Eh                 ; Now, close the file
        int     21h
        jc      Disk_Error

        push    esi
        mov     esi,Offset Str_MakeFile ; Write file we create
        call    Str_Write
        pop     esi
        call    Str_Write
        mov     esi,Offset Str_Done     ; Yes! We are finished!!!!
        call    Str_Write


; Normal exit
Exit:   mov     ax,04C00h
        int     21h


; Exit with error message in ESI
Exit_Write:
        call    Str_Write
Exit2:  mov     ax,04CFFh
        int     21h

; File is not found. EDX = File name
Not_Found:
        push    esi
        mov     esi,Offset Str_Err3
        call    Str_Write
        pop     esi
        call    Str_Write
        call    New_Line
        call    Exit2


; Exit, with disk error
Disk_Error:
        push    eax
        mov     esi,Offset Str_Err2
        call    Str_Write
        pop     eax                     ; Write error code
        movzx   eax,ax
        mov     cx,2
        call    Write_Dec
        call    New_Line
        jmp     Exit2
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ



; Open and read file into internal buffer.
; ESI = File name, EDI = Where to load, EAX = Bytes loaded
Proc    Load_File
        mov     ax,3D00h                ; Open /w read accsess
        mov     edx,esi
        int     21h
        jnc     @@10
        cmp     ax,2                    ; File not found?
        je      Not_Found
        cmp     ax,3                    ; Path not found?
        je      Not_Found
        stc                             ; Other error...
        ret

; File opend, AX = Handle
@@10:   mov     bx,ax

        mov     ecx,5000                ; Try to load 5KB
        cmp     edi,Offset Buffer       ; Are we loading index file?
        je      @@30                    ; Yes, skipp seeking

        mov     ax,04200h               ; Skipp 16 byte header (seek)
        mov     edx,16
        int     21h
        jc      @@99
        mov     ecx,20000               ; Try to load 20KB

@@30:   mov     ah,03Fh                 ; Now load file into buffer.
        mov     edx,edi
        int     21h
        jc      @@99

        push    eax
        mov     ah,03Eh                 ; Now, close the file
        int     21h
        pop     eax

@@99:   ret
EndP    Load_File
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                             *** DATA ***
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Str_Intro       db      CR,LF,'Bolder Dash level joining utility. Starting to join levels...',CR,LF,0
Str_Join        db      CR,LF,'Loading file: ',0
Str_Join2       db      ', joining OK!',0
Str_MakeFile    db      CR,LF,'Writing all the new levels to file: ',0
Str_Done        db      CR,LF,LF,'Well, it looks like it went fine :)',CR,LF,0

Str_Err1        db      CR,LF,'I need a file, with all the level names to join, and the name of the new file...',CR,LF,0
Str_Err2        db      CR,LF,'ERROR: Some sort of disk error. DOS error code: ',0
Str_Err3        db      CR,LF,'ERROR: File not found: ',0
Str_GenError    db      CR,LF,'ERROR: Somthing screwed upp!',CR,LF,0
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
EndS            BigSeg



SEGMENT         U_Data
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;                          *** U - DATA ***
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
        ALIGN   DWORD

Mem_Offset      dd      ?

Buffer          db      5000 Dup(?)     ; 5K buffer
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
EndS            U_Data



ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
SEGMENT Stack_Seg       Para    Stack           'STACK'         USE32
        db      128 Dup (?)             ; DOS32 - Stack
        dd      64 Dup (?)              ; Our stack
EndS    Stack_Seg
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
        End     Start
